﻿var proofOfExistenceApp = angular.module('proofOfExistenceApp', ['ngResource']);

proofOfExistenceApp.controller('AppCtrl', function AppCtrl($scope, $window) {

    var qrurl = "https://chart.googleapis.com/chart?cht=qr&chs=200x200&chl=bitcoin://";
    var easywallet_baseurl = "https://easywallet.org/api/v1/";
    var poe_url = "http://www.proofofexistence.com/";

    var poe_detailurl = poe_url + "detail/";
    var poe_statusurl = poe_url + "api/v1/status?d=" + $scope.digest;
    var poe_registerurl = poe_url + "api/v1/register?d=" + $scope.digest;

    var easywallet_walleturl = easywallet_baseurl + "w/" + $scope.wallet_id;

    var registrations = "Registrations";
    var wallets = "Wallets";

    var satoshisInBitcoin = 100000000;
    var context;

    $scope.get_status = function () {
        $.ajax({
            url: "../_api/SP.WebProxy.invoke",
            type: "POST",
            data: JSON.stringify(
                {
                    "requestInfo": {
                        "__metadata": { "type": "SP.WebRequestInfo" },
                        "Url": poe_statusurl,
                        "Method": "GET",
                        "Headers": {
                            "results": [{
                                "__metadata": { "type": "SP.KeyValue" },
                                "Key": "Accept",
                                "Value": "application/json;odata=verbose",
                                "ValueType": "Edm.String"
                            }]
                        }
                    }
                }),
            headers: {
                "Accept": "application/json;odata=verbose",
                "Content-Type": "application/json;odata=verbose",
                "X-RequestDigest": $("#__REQUESTDIGEST").val()
            },
            success: function (data) {
                if (data.d.Invoke.StatusCode == 200) {
                    var result = JSON.parse(data.d.Invoke.Body);

                    if (result.success) {

                        if (($scope.status != result.status) && (result.status == "pending" || result.status == "confirmed")) {

                            var oList = context.get_web().get_lists().getByTitle(registrations);
                            var listItem = oList.getItemById($scope.itemid);

                            listItem.set_item('PoE_Status', result.status);

                            listItem.update();

                            context.executeQueryAsync(function () {
                                $scope.status = result.status;

                                $scope.$apply();

                            }, function (error) {
                                $scope.error = true;
                                $scope.error_message = error.toString();
                                $scope.$apply();
                            });

                        }
                    }
                    else {
                        $scope.status = result.reason;
                        $scope.$apply();
                    }
                }
                else {
                    $scope.error = true;
                    $scope.error_message = "Service unavailable";

                    $scope.$apply();
                }
                
            },
            error: function (error) {
                $scope.error = true;
                $scope.error_message = error.toString();
                $scope.$apply();

            }
        });
    }
    
    $scope.create_new_wallet = function () {
        var url = easywallet_baseurl + "/new_wallet";

        $.ajax({
            url: "../_api/SP.WebProxy.invoke",
            type: "POST",
            data: JSON.stringify(
                {
                    "requestInfo": {
                        "__metadata": { "type": "SP.WebRequestInfo" },
                        "Url": url,
                        "Method": "POST",
                        "Headers": {
                            "results": [{
                                "__metadata": { "type": "SP.KeyValue" },
                                "Key": "Accept",
                                "Value": "application/json;odata=verbose",
                                "ValueType": "Edm.String"
                            }]
                        }
                    }
                }),
            headers: {
                "Accept": "application/json;odata=verbose",
                "Content-Type": "application/json;odata=verbose",
                "X-RequestDigest": $("#__REQUESTDIGEST").val()
            },
            success: function (data) {
                if (data.d.Invoke.StatusCode == 200) {
                    var result = JSON.parse(data.d.Invoke.Body);

                    if (result.successful) {
                        var oList = context.get_web().get_lists().getByTitle(wallets);

                        var itemCreateInfo = new SP.ListItemCreationInformation();
                        var oListItem = oList.addItem(itemCreateInfo);

                        oListItem.set_item('Title', result.wallet_id);
                        oListItem.update();
                        context.load(oListItem);

                        context.executeQueryAsync(function () {
                            $scope.wallet_id = result.wallet_id;
                            $scope.wallet_balance = 0;
                            $scope.$apply();

                            $scope.get_wallet_address();


                        }, function (error) {
                        });
                    }
                }
              
            },
            error: function (error) {
            }
        });

    }

    $scope.get_wallet_address = function() {
        var url = easywallet_walleturl + "/address";

        $.ajax({
            url: "../_api/SP.WebProxy.invoke",
            type: "POST",
            data: JSON.stringify(
                {
                    "requestInfo": {
                        "__metadata": { "type": "SP.WebRequestInfo" },
                        "Url": url,
                        "Method": "GET",
                        "Headers": {
                            "results": [{
                                "__metadata": { "type": "SP.KeyValue" },
                                "Key": "Accept",
                                "Value": "application/json;odata=verbose",
                                "ValueType": "Edm.String"
                            }]
                        }
                    }
                }),
            headers: {
                "Accept": "application/json;odata=verbose",
                "Content-Type": "application/json;odata=verbose",
                "X-RequestDigest": $("#__REQUESTDIGEST").val()
            },
            success: function (data) {
                if (data.d.Invoke.StatusCode == 200) {
                    var result = JSON.parse(data.d.Invoke.Body);

                    if (result.successful) {
                        $scope.wallet_address = result.address;
                        $scope.wallet_qr = qrurl + result.address;
                        $scope.$apply();
                    }
                }
            },
            error: function (error) {
            }
        });

    }

    $scope.get_wallet_balance = function () {
        var url = easywallet_walleturl + "/balance";

        $.ajax({
            url: "../_api/SP.WebProxy.invoke",
            type: "POST",
            data: JSON.stringify(
                {
                    "requestInfo": {
                        "__metadata": { "type": "SP.WebRequestInfo" },
                        "Url": url,
                        "Method": "GET",
                        "Headers": {
                            "results": [{
                                "__metadata": { "type": "SP.KeyValue" },
                                "Key": "Accept",
                                "Value": "application/json;odata=verbose",
                                "ValueType": "Edm.String"
                            }]
                        }
                    }
                }),
            headers: {
                "Accept": "application/json;odata=verbose",
                "Content-Type": "application/json;odata=verbose",
                "X-RequestDigest": $("#__REQUESTDIGEST").val()
            },
            success: function (data) {
                if (data.d.Invoke.StatusCode == 200) {
                    var result = JSON.parse(data.d.Invoke.Body);

                    if (result.successful) {
                        $scope.wallet_balance = result.balance;
                        $scope.$apply();
                    }
                }
            },
            error: function (error) {
            }
        });
    }
   

    $scope.register = function () {
        $.ajax({
            url: "../_api/SP.WebProxy.invoke",
            type: "POST",
            data: JSON.stringify(
                {
                    "requestInfo": {
                        "__metadata": { "type": "SP.WebRequestInfo" },
                        "Url": poe_registerurl,
                        "Method": "GET",
                        "Headers": {
                            "results": [{
                                "__metadata": { "type": "SP.KeyValue" },
                                "Key": "Accept",
                                "Value": "application/json;odata=verbose",
                                "ValueType": "Edm.String"
                            }]
                        }
                    }
                }),
            headers: {
                "Accept": "application/json;odata=verbose",
                "Content-Type": "application/json;odata=verbose",
                "X-RequestDigest": $("#__REQUESTDIGEST").val()
            },
            success: function (data) {

                var result = JSON.parse(data.d.Invoke.Body);
                if (result.success) {
                    var oList = context.get_web().get_lists().getByTitle(registrations);

                    var itemCreateInfo = new SP.ListItemCreationInformation();
                    var oListItem = oList.addItem(itemCreateInfo);

                    oListItem.set_item('Title', $scope.digest);
                    oListItem.set_item('PoE_Status', "registered");
                    oListItem.set_item('PoE_PayAddress', result.pay_address);
                    oListItem.set_item('PoE_Price', result.price.toString());

                    var fvalue = new SP.FieldUrlValue();
                    fvalue.set_url($scope.filelink);
                    fvalue.set_description($scope.filename);
                    oListItem.set_item("PoE_FileLink", fvalue);

                    oListItem.update();
                    context.load(oListItem);

                    context.executeQueryAsync(function () {
                        $scope.itemid = oListItem.get_id();
                        $scope.pay_address = result.pay_address;
                        $scope.price = result.price;
                        $scope.registered_at = oListItem.get_item("Created").toString();
                        $scope.qr_img_link = qrurl + result.pay_address + "?amount=" + ((result.price / satoshisInBitcoin).toFixed(8)).toString();

                        if ($scope.wallet_id != null && $scope.wallet_balance >= (((result.price / satoshisInBitcoin) + 0.0001) * 1.01)) {

                            var walleturl = easywallet_walleturl + "/payment";

                            $.ajax({
                                url: "../_api/SP.WebProxy.invoke",
                                type: "POST",
                                data: JSON.stringify(
                                    {
                                        "requestInfo": {
                                            "__metadata": { "type": "SP.WebRequestInfo" },
                                            "Url": walleturl,
                                            "Method": "POST",
                                            "Headers": {
                                                "results": [{
                                                    "__metadata": { "type": "SP.KeyValue" },
                                                    "Key": "Accept",
                                                    "Value": "text/plain",
                                                    "ValueType": "Edm.String"
                                                },
                                                {
                                                    "__metadata": { "type": "SP.KeyValue" },
                                                    "Key": "Content-Type",
                                                    "Value": "application/x-www-form-urlencoded",
                                                    "ValueType": "Edm.String"
                                                }]
                                            },
                                            "Body": "address=" + result.pay_address + "&amount=" + (result.price / satoshisInBitcoin)
                                        }
                                    }),
                                headers: {
                                    "Accept": "application/json;odata=verbose",
                                    "Content-Type": "application/json;odata=verbose",
                                    "X-RequestDigest": $("#__REQUESTDIGEST").val()
                                },
                                success: function (data) {

                                    if (data.d.Invoke.StatusCode == 200) {
                                        var result = JSON.parse(data.d.Invoke.Body);

                                        if (result.successful) {
                                            oListItem.set_item('PoE_Status', "pending");

                                            oListItem.update();

                                            context.executeQueryAsync(function () {
                                                $scope.status = "pending";
                                                $scope.detail_link = poe_detailurl + $scope.digest;
                                                $scope.$apply();

                                                $scope.get_wallet_balance();

                                            }, function () {
                                            });

                                        }
                                        else {
                                            $scope.status = "registered";
                                            $scope.$apply();
                                        }
                                    }
                                    else {
                                        $scope.status = "registered";
                                        $scope.$apply();

                                    }
                                },
                                error: function (error) {
                                    $scope.error = true;
                                    $scope.error_message = error.toString();
                                    $scope.$apply();

                                }
                            });



                        }
                        else {
                            $scope.status = "registered";
                            $scope.$apply();
                        }

                    }, function (error) {
                        $scope.error = true;
                        $scope.error_message = error.toString();
                        $scope.$apply();
                    });

                }
            },
            error: function (error) {
                $scope.error = true;
                $scope.error_message = error.toString();
                $scope.$apply();

            }
        });
    }

    $scope.load_wallet = function () {
        var oList = context.get_web().get_lists().getByTitle(wallets);

        var camlQuery = new SP.CamlQuery();
        camlQuery.set_viewXml('<View><RowLimit>1</RowLimit></View>');
        var collListItem = oList.getItems(camlQuery);

        context.load(
            collListItem,
            'Include(Id, Title)'
        );

        context.executeQueryAsync(function (sender, args) {
            var listItemEnumerator = collListItem.getEnumerator();

            while (listItemEnumerator.moveNext()) {
                var oListItem = listItemEnumerator.get_current();

                $scope.wallet_id = oListItem.get_item('Title');

                $scope.$apply();

                $scope.get_wallet_address();
                $scope.get_wallet_balance();
            }

        }, function (error) {
            $scope.error = true;
            $scope.error_message = error.toString();
            $scope.$apply();
        });
    }

    $scope.show_items = function () {
        var oList = context.get_web().get_lists().getByTitle(registrations);
        var camlQuery = new SP.CamlQuery();
        camlQuery.set_viewXml('<View><RowLimit>100</RowLimit></View>');
        var collListItem = oList.getItems(camlQuery);

        context.load(
            collListItem,
            'Include(Id, Title, PoE_Status, PoE_PayAddress, PoE_Price, PoE_FileLink, Created)'
        );

        context.executeQueryAsync(function (sender, args) {
            var listItemEnumerator = collListItem.getEnumerator();

            var allRegistrations = new Array();

            while (listItemEnumerator.moveNext()) {
                var oListItem = listItemEnumerator.get_current();
                
                allRegistrations.push({
                    itemid: oListItem.get_id(),
                    status: oListItem.get_item('PoE_Status'),
                    registered_at: oListItem.get_item("Created").toString(),
                    filelink: oListItem.get_item("PoE_FileLink").get_url(),
                    filename: oListItem.get_item("PoE_FileLink").get_description(),
                    pay_address: oListItem.get_item('PoE_PayAddress'),
                    price: oListItem.get_item('PoE_Price'),
                    detail_link: poe_detailurl + oListItem.get_item('Title')
                 });


            }

            $scope.all_registrations = allRegistrations;
            $scope.$apply();

            $('.nav-tabs a[href="#content"]').tab('show');

        }, function (error) {
            $scope.error = true;
            $scope.error_message = error.toString();
            $scope.$apply();
        });
    }

    $scope.get_item = function () {
        var factory = new SP.ProxyWebRequestExecutorFactory($scope.appweburl);
        context.set_webRequestExecutorFactory(factory);
        var appContextSite = new SP.AppContextSite(context, $scope.hostweburl);

        var list = appContextSite.get_web().get_lists().getById($scope.doclibid);
        var listItem = list.getItemById($scope.docid);
        context.load(listItem);

        var itemFile = listItem.get_file();
        context.load(itemFile);

        context.executeQueryAsync(
            function () {
                $scope.serverrelativeurl = itemFile.get_serverRelativeUrl();
                $scope.filename = itemFile.get_name();
                $scope.filelink = makeAbsUrl($scope.serverrelativeurl);

                var requestor = new SP.RequestExecutor($scope.appweburl);
                requestor.executeAsync(
                {
                    url: $scope.appweburl + "/_api/SP.AppContextSite(@target)/web/GetFileByServerRelativeUrl('" + $scope.serverrelativeurl + "')/$value?@target='" + $scope.hostweburl + "'",
                    type: "GET",
                    success: function (data) {
                        CryptoJS.SHA256(data.body.toString(), function (p) {
                        },
                            function (hash) {
                                $scope.digest = hash.toString();

                                var oList = context.get_web().get_lists().getByTitle(registrations);
                                var camlQuery = new SP.CamlQuery();

                                camlQuery.set_viewXml('<View><Query><Where><Eq><FieldRef Name=\'Title\'/>' +
                                    '<Value Type=\'Text\'>' + $scope.digest + '</Value></Eq></Where></Query><RowLimit>1</RowLimit></View>');

                                var collListItem = oList.getItems(camlQuery);

                                context.load(collListItem);

                                context.executeQueryAsync(function (sender, args) {
                                    var count = collListItem.get_count();

                                    if (count == 0) {
                                        $scope.get_status();
                                    }
                                    else {
                                        var listItemEnumerator = collListItem.getEnumerator();

                                        while (listItemEnumerator.moveNext()) {
                                            var oListItem = listItemEnumerator.get_current();
                                            $scope.itemid = oListItem.get_id();
                                            $scope.status = oListItem.get_item('PoE_Status');
                                            $scope.pay_address = oListItem.get_item('PoE_PayAddress');
                                            $scope.registered_at = oListItem.get_item("Created").toString();
                                            $scope.price = oListItem.get_item('PoE_Price');
                                            $scope.detail_link = poe_detailurl + $scope.digest;
                                            $scope.qr_img_link = qrurl + $scope.pay_address + "?amount=" + (($scope.price / satoshisInBitcoin).toFixed(8)).toString();

                                            $scope.$apply();

                                            if ($scope.status == "pending" || $scope.status == "registered") {
                                                $scope.get_status();
                                            }
                                        }
                                    }

                                }, function (error) {

                                    $scope.error = true;
                                    $scope.error_message = error.toString();
                                    $scope.$apply();

                                });

                            });
                    },
                    error: function (error) {
                        $scope.error = true;
                        $scope.error_message = error.toString();
                        $scope.$apply();

                    }
                });
            },
            function (error) {
                $scope.error = true;
                $scope.error_message = error.toString();
                $scope.$apply();
            }
        );
        



    }

    $scope.load_sprequestexecutor = function(callback) {
        var scriptbase = $scope.hostweburl + '/_layouts/15/';
        $.getScript(scriptbase + 'SP.RequestExecutor.js', callback);
    }

    $window.init = function () {

        $scope.isdlg = ($.url().param("IsDlg") == 1);

        if ($scope.isdlg) {
            $('head').append('<link rel="stylesheet" href="../Content/AppDlg.css" type="text/css" />');
        }

        $scope.hostweburl = $.url().param("SPHostUrl");
        $scope.appweburl = $.url().param("SPAppWebUrl");

        $scope.doclibid = $.url().param("SPListId");
        $scope.docid = $.url().param("SPListItemId");

        context = new SP.ClientContext($scope.appweburl);

        $scope.load_wallet();

        if ($scope.doclibid != null && $scope.docid != null) {
            $scope.$apply($scope.load_sprequestexecutor($scope.get_item));
        }
        else {
            $scope.$apply($scope.load_sprequestexecutor($scope.show_items));
        }
    };
  
});

$(document).ready(function () {
    window.init();
});

